const ncname = `[a-zA-Z_][\\-\\.0-9_a-zA-Z]*`; //标签名称
const qnameCapture = `((?:${ncname}\\:)?${ncname})`; // <span:xx> 标签名
const startTagOpen = new RegExp(`^<${qnameCapture}`); //标签开头的正则，捕获的内容是标签名
const endTag = new RegExp(`^<\\/${qnameCapture}[^>]*>`); //匹配标签结尾的  </div>
const attribute =
  /^\s*([^\s"'<>\/=]+)(?:\s*(=)\s*(?:"([^"]*)"+|'([^']*)'+|([^\s"'=<>`]+)))?/;
const startTagClose = /^\s*(\/?)>/;
const defaultTagRE = /\{\{((?:.|\r?\n)+?)\}\}/g;
let root;
let createParent;
// 数据结构  栈
let stack = [];
//开始标签
function startTag(tag, attrs) {
  //   console.log(tag, attrs, "标签属性");
  //   console.log(tag, attrs);
  let element = createASTElement(tag, attrs);
  //   console.log(element, "33");
  if (!root) {
    root = element;
  }
  createParent = element;

  stack.push(createParent);
  //   console.log(stack[0]);
}
//获取文本
function charts(text) {
  text = text.replace(/\s/g, "");

  if (text) {
    createParent.childrens.push({
      type: 3,
      text,
    });
  }
  //   console.log(text, "文本");
}
function end(end) {
  let element = stack.pop();

  createParent = stack[stack.length - 1];
  //   console.log(createParent);
  if (createParent) {
    //元素闭合
    element.parent = createParent.tag;
    createParent.childrens.push(element);
  }
} //结束标签
function createASTElement(tag, attrs) {
  return {
    tag, //元素
    attrs, // 属性
    childrens: [], //子节点
    type: 1,
    parent: null,
  };
}

export function parseHTML(html) {
  // <div id="app"> hello {{msg}}  </div>    // 开始标签   文本    结束标签
  while (html) {
    //html  为空结束
    let textEnd = html.indexOf("<"); // 0
    if (textEnd === 0) {
      //(1) 开始标签
      const startTagMatch = parseStartTag(); //开始解析标签的内容
      //   console.log(startTagMatch);
      if (startTagMatch) {
        startTag(startTagMatch.tagName, startTagMatch.attrs);
        continue;
      }
      //(2)结束标签
      let endTagMatch = html.match(endTag); //结束标签
      if (endTagMatch) {
        advance(endTagMatch[0].length);
        end(endTagMatch[1]);
        continue;
      }
    }
    if (textEnd > 0) {
      //获取文本内容
      let text = html.substring(0, textEnd);
      //   console.log(text, "text");
      advance(text.length);
      charts(text);
      continue;
    }
  }
  function parseStartTag() {
    //解析开始标签

    const startTag = html.match(startTagOpen); //1 结果  2 null

    if (startTag) {
      //创建一个语法树
      let match = {
        tagName: startTag[1],
        attrs: [],
      };

      advance(startTag[0].length); //删除开始标签
      //属性
      // 注意 多个 遍历

      let attr;
      var end;

      while (
        !(end = html.match(startTagClose)) &&
        (attr = html.match(attribute))
      ) {
        match.attrs.push({ name: attr[1], value: attr[3] || attr[4] });

        advance(attr[0].length);
        continue;
      }

      if ((end = html.match(startTagClose))) {
        advance(end[0].length);
        return match;
      }
    }
  }
  function advance(n) {
    html = html.substring(n);
  }
  //   console.log(root);
  return root;
}
